﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Common;
using Common.ExpressionParsing;
using Common.Exceptions;
using Tools;

namespace Service.BusinessLogic
{
    public class CustomFunctionExtension : IFunctionVisitorExtension
    {
        #region IFunctionVisitorExtension Members

        public IList<string> Identifiers
        {
            get
            {
                return new List<String>()
                    {
                        "CustomFunc"
                    };
            }
        }

        public object Execute(string functionIdentifier, LogicalExpression[] functionParameters, LogicalExpressionVisitor visitor)
        {
            switch (functionIdentifier)
            {
                #region CustomFunc

                case "customfunc":
                    Object result = null;

                    if (functionParameters.Length < 1)
                        throw new BusinessLogicException(
                            ExceptionHelper.excode_customfunc_takes_1_or_more_argument
                            , "CustomFunc() takes 1 or more argument(s)");

                    String funcCode = Convert.ToString(visitor.Evaluate(functionParameters[0]));
                    FunctionInfo funcInfo = ExpressionParserConfig.GetFunctionInfo(funcCode);

                    List<Object> funcParams = new List<Object>();
                    for (int i = 1; i < functionParameters.Length; i++)
                    {
                        LogicalExpression paramExpr = functionParameters[i];
                        paramExpr.Accept(visitor);

                        Object param = visitor.Result;
                        funcParams.Add(param);
                    }

                    result = Invocator.Invoke(funcInfo, funcParams.ToArray());

                    return result;

                #endregion CustomFunc


                default:
                    throw new IncorrectArgumentException("functionIdentifier");
            }

            throw new IncorrectArgumentException("functionIdentifier");
        }

        #endregion
    }
}